// 设备管理    冯

var express = require('express');
var router = express.Router();
const db = require('../../db/db');
// 导入解析 formdata 格式表单数据的包
const multer = require('multer') // 虽然 app.js 中已经配置了全局 Multer，但这里导入是为了类型提示或局部使用，实际文件上传由全局 Multer 处理
// 导入处理路径的核心模块
const path = require('path') // 导入 path 模块
// 导入文件系统模块
const fs = require('fs'); // 导入 fs 模块


//获取牲畜列表信息 (模糊查询)
router.get('/livestockSearch', (req, res) => {
  let { pastureID, houseId, strKey } = req.query;
  let sql;
  if (!pastureID && !houseId && !strKey) {
    sql = `SELECT h.f_id,h.f_imei,h.f_title,h.f_sex,h.f_birthday,h.f_state,
    p.F_Title AS pasture_Title, hh.F_Title AS house_Title ,pp.F_Title AS livestock_Type
    FROM nc_livestock h
    LEFT JOIN nc_livestock_type pp ON h.F_Type_Id = pp.F_Id
    LEFT JOIN nc_pasture p ON h.F_Org_Id = p.F_Id
    LEFT JOIN nc_house hh ON h.F_HouseId = hh.F_Id`;
  } else {
    sql = `SELECT h.f_id,h.f_imei,h.f_title,h.f_sex,h.f_birthday,h.f_state,
    p.F_Title AS pasture_Title, hh.F_Title AS house_Title ,pp.F_Title AS livestock_Type
    FROM nc_livestock h
    LEFT JOIN nc_livestock_type pp ON h.F_Type_Id = pp.F_Id
    LEFT JOIN nc_pasture p ON h.F_Org_Id = p.F_Id
    LEFT JOIN nc_house hh ON h.F_HouseId = hh.F_Id
    WHERE h.F_Org_Id
    LIKE '%${pastureID}%' OR h.F_HouseId LIKE '%${houseId}%' OR h.F_Title LIKE '%${strKey}%'`;
  }
  console.log(sql);

  db.query(sql, (err, result) => {
    if (err) {
      // 使用 res.cc 统一处理错误
      res.cc(0, '查询失败');
    } else {
      res.cc(200, '查询成功', result); // 使用 res.cc 返回成功数据
    }
  });
});


//智能耳标管理

//获取智能耳标列表信息 (模糊分页查询)
router.get('/earSearch', (req, res) => {
  let { pageSize, pageNum, deviceImei, livestockImei } = req.query;

  // 并且提供默认值，例如每页10条，从第一页开始
  const parsedPageSize = parseInt(pageSize) || 5;
  const parsedPageNum = parseInt(pageNum) || 1;
  const offset = (parsedPageNum - 1) * parsedPageSize;
  let sql;
  let sql1;
  if (!deviceImei && !livestockImei) {
    sql = `SELECT
  h.*,
  p.F_IMEI AS livestockImei,
  p.F_Title AS livestock_Title,
  hh.F_Title AS house_Title,
  pp.F_Title AS pasture_Title
  FROM nc_device_eartag AS h
  LEFT JOIN nc_livestock AS p ON h.F_LiveStockId = p.F_Id
  LEFT JOIN nc_pasture pp ON p.F_Org_Id = pp.F_Id
  LEFT JOIN nc_house hh ON p.F_HouseId = hh.F_Id
  LIMIT ${offset}, ${parsedPageSize}`;
    sql1 = `select count(*) as total from nc_device_eartag`;
  } else {
    sql = `SELECT
   h.*,
p.F_IMEI AS livestockImei,
  p.F_Title AS livestock_Title,
  hh.F_Title AS house_Title,
  pp.F_Title AS pasture_Title
  FROM nc_device_eartag AS h
  LEFT JOIN nc_livestock AS p ON h.F_LiveStockId = p.F_Id
  LEFT JOIN nc_pasture pp ON p.F_Org_Id = pp.F_Id
  LEFT JOIN nc_house hh ON p.F_HouseId = hh.F_Id
WHERE h.F_IMEI LIKE '%${deviceImei}%' OR h.F_LivestockId LIKE '%${livestockImei}%'
LIMIT ${offset}, ${parsedPageSize}`;
    sql1 = `select count(*) as total from nc_device_eartag where F_IMEI LIKE '%${deviceImei}%' OR F_LiveStockId LIKE '%${livestockImei}%'`;
  }

  db.query(sql, (err, result) => {
    if (err) {
      res.cc(0, '服务器错误'); // 使用 res.cc
      return;
    } else if (result.length === 0) {
      res.cc(0, '暂无数据'); // 使用 res.cc
      return;
    }
    //获取总条数
    db.query(sql1, (err, countResult) => {
      if (err) {
        res.cc(0, '获取总条数失败'); // 使用 res.cc
        return;
      }
      res.send({code:200, message:'智能耳标列表查询成功', data:result, total:countResult[0].total}); // 使用 res.cc 返回数据和总数
    });
  });
});

//获取耳标信息详情
router.get('/earDetail', (req, res) => {
  let { id } = req.query;
  let sql =
    `select h.*,p.F_Title as livestock_Title,n.F_Title as pasture_Title ,m.F_Title as house_Title
  from nc_device_eartag h
  left join nc_livestock p on h.F_LiveStockId = p.F_Id
  left join nc_pasture n on p.F_Org_Id = n.F_Id
  left join nc_house m on p.F_HouseId = m.F_Id
  where h.F_Id ='${id}'`;
  console.log(sql);

  db.query(sql, [id], (err, result) => {
    if (err) {
      res.cc(0, '服务器错误'); // 使用 res.cc
      return;
    }
    if (result.length === 0) {
      res.cc(0, '暂无数据'); // 使用 res.cc
      return;
    }
    res.cc(200, '查询成功', result[0]); // 使用 res.cc 返回单条数据
  });
});

//耳标信息批量删除
router.post('/earDelete', (req, res) => {
  let { ids } = req.body;
  console.log(ids);
  if (!ids || ids.length === 0) {
    res.cc(0, '请选择要删除的耳标'); // 使用 res.cc
    return;
  }
  // 确保 ids 是一个数组，并处理单条和多条删除的情况
  const idList = Array.isArray(ids) ? ids : [ids];
  const idString = "'" + idList.join("','") + "'";

  let sql = `delete from nc_device_eartag where F_id in (${idString})`;
  console.log(sql);
  db.query(sql, (err, result) => {
    if (err) {
      res.cc(0, '删除失败'); // 使用 res.cc
      return;
    }
    // 检查是否删除了任何行
    if (result.affectedRows === 0) {
       res.cc(0, '未找到匹配的耳标进行删除'); // 或者根据业务逻辑返回失败
    } else {
       res.cc(200, '删除成功'); // 使用 res.cc
    }
  });
});


//新增耳标信息(待修改 表的关联性)
router.post('/earAdd', (req, res) => {
  let { imei, brand, livestId } = req.body;
  //id为时间戳
  const id = Date.now(); // 使用 const
  let sql = `insert into nc_device_eartag(F_id,F_IMEI,F_Brand,F_LivestockId) values('${id}','${imei}','${brand}','${livestId}')`;
  console.log(sql);
  db.query(sql, (err, result) => {
    // 增加更详细的输入验证
    if (err) {
       console.error("数据库错误:", err);
       return res.cc(0, '数据库操作失败');
    }
    if (!imei || !brand || !livestId) { // 检查字段是否为空或 undefined
      return res.cc(0, '输入字段有误');
    }
    res.cc(200, '耳标信息新增成功'); // 使用 res.cc
  });
});

// 修改耳标信息
router.post('/earUpdate', (req, res) => {
  let { id, imei, brand, livestId } = req.body;
  // 增加输入验证
  if (!id || !imei || !brand || !livestId) {
     return res.cc(0, '输入字段不完整或ID缺失');
  }
  let sql = `update nc_device_eartag set F_IMEI = '${imei}',F_Brand = '${brand}',F_LivestockId = '${livestId}' where F_id = '${id}'`;
  console.log(sql);
  db.query(sql, (err, result) => {
    if (err) {
      console.error("数据库错误:", err);
      return res.cc(0, '耳标信息修改失败'); // 使用 res.cc
    }
    // 检查是否修改了任何行
    if (result.affectedRows === 0) {
        res.cc(0, '未找到匹配的耳标进行修改'); // 或者根据业务逻辑返回失败
    } else {
       res.cc(200, '耳标信息修改成功'); // 使用 res.cc
    }
  });
});




//智能项圈管理
//获取智能项圈列表信息 (模糊分页查询)
router.get('/collarSearch', (req, res) => {
  let { pageSize, pageNum, deviceImei, livestockImei } = req.query;

  // 并且提供默认值，例如每页10条，从第一页开始
  const parsedPageSize = parseInt(pageSize) || 5;
  const parsedPageNum = parseInt(pageNum) || 1;
  const offset = (parsedPageNum - 1) * parsedPageSize;
  let sql;
  let sql1;
  if (!deviceImei && !livestockImei) {
    sql = `SELECT
  h.*,
  p.F_IMEI AS livestockImei,
  p.F_Title AS livestock_Title,
  hh.F_Title AS house_Title,
  pp.F_Title AS pasture_Title
  FROM nc_device_kv AS h
  LEFT JOIN nc_livestock AS p ON h.liveid = p.F_Id
  LEFT JOIN nc_pasture pp ON p.F_Org_Id = pp.F_Id
  LEFT JOIN nc_house hh ON p.F_HouseId = hh.F_Id
  LIMIT ${offset}, ${parsedPageSize}`;
    sql1 = `select count(*) as total from nc_device_kv`;
  } else {
    sql = `SELECT
   h.*,
  p.F_IMEI AS livestockImei,
  p.F_Title AS livestock_Title,
  hh.F_Title AS house_Title,
  pp.F_Title AS pasture_Title
  FROM nc_device_kv AS h
  LEFT JOIN nc_livestock AS p ON h.liveid = p.F_Id
  LEFT JOIN nc_pasture pp ON p.F_Org_Id = pp.F_Id
  LEFT JOIN nc_house hh ON p.F_HouseId = hh.F_Id
WHERE h.miei LIKE '%${deviceImei}%' OR h.liveid LIKE '%${livestockImei}%'
LIMIT ${offset}, ${parsedPageSize}`;
    sql1 = `select count(*) as total from nc_device_kv where miei LIKE '%${deviceImei}%' OR liveid LIKE '%${livestockImei}%'`;
  }

  db.query(sql, (err, result) => {
    if (err) {
      res.cc(0, '服务器错误'); // 使用 res.cc
      return;
    } else if (result.length === 0) {
      res.cc(0, '暂无数据'); // 使用 res.cc
      return;
    }
    //获取总条数
    db.query(sql1, (err, countResult) => {
      if (err) {
        res.cc(0, '获取总条数失败'); // 使用 res.cc
        return;
      }
      res.send({code:200, message:'智能项圈列表查询成功', data:result, total:countResult[0].total}); // 使用 res.cc
    });
  });
});

//获取项圈信息详情
router.get('/collarDetail', (req, res) => {
  let { id } = req.query;
  let sql =
    `select h.*,p.F_Title as livestock_Title,n.F_Title as pasture_Title ,m.F_Title as house_Title
  from nc_device_kv h
  left join nc_livestock p on h.liveid = p.F_Id
  left join nc_pasture n on p.F_Org_Id = n.F_Id
  left join nc_house m on p.F_HouseId = m.F_Id
  where h.id ='${id}'`;
  console.log(sql);

  db.query(sql, [id], (err, result) => {
    if (err) {
      res.cc(0, '服务器错误'); // 使用 res.cc
      return;
    }
     if (result.length === 0) {
      res.cc(0, '暂无数据'); // 使用 res.cc
      return;
    }
    res.cc(200, '查询成功', result[0]); // 使用 res.cc 返回单条数据
  });
});

//项圈信息批量删除
router.post('/collarDelete', (req, res) => {
  let { ids } = req.body;
  console.log(ids);
  if (!ids || ids.length === 0) {
    res.cc(0, '请选择要删除的项圈'); // 使用 res.cc
    return;
  }
  const idList = Array.isArray(ids) ? ids : [ids];
  const idString = "'" + idList.join("','") + "'";
  let sql = `delete from nc_device_kv where id in (${idString})`;
  console.log(sql);
  db.query(sql, (err, result) => {
    if (err) {
      res.cc(0, '删除失败'); // 使用 res.cc
      return;
    }
     if (result.affectedRows === 0) {
       res.cc(0, '未找到匹配的项圈进行删除'); // 或者根据业务逻辑返回失败
    } else {
       res.cc(200, '删除成功'); // 使用 res.cc
    }
  });
})


//新增项圈信息(待修改 表的关联性)
router.post('/collarAdd', (req, res) => {
  let { imei, brand, livestId } = req.body;
  const id = Date.now(); // 使用 const
  if (!imei || !brand || !livestId) { // 增加输入验证
     return res.cc(0, '输入字段有误');
  }
  let sql = `insert into nc_device_kv(id,miei,dtype,liveid) values('${id}','${imei}','${brand}','${livestId}')`;
  console.log(sql);
  db.query(sql, (err, result) => {
    if (err) {
      console.error("数据库错误:", err);
      return res.cc(0, '数据库操作失败'); // 使用 res.cc
    }
    res.cc(200, '项圈信息新增成功'); // 使用 res.cc
  });
});

// 修改项圈信息
router.post('/collarUpdate', (req, res) => {
  let { id, imei, brand, livestId } = req.body;
  if (!id || !imei || !brand || !livestId) { // 增加输入验证
     return res.cc(0, '输入字段不完整或ID缺失');
  }
  let sql = `update nc_device_kv set miei = '${imei}',dtype= '${brand}',liveid = '${livestId}' where id = '${id}'`;
  console.log(sql);
  db.query(sql, (err, result) => {
    if (err) {
      console.error("数据库错误:", err);
      return res.cc(0, '项圈信息修改失败'); // 使用 res.cc
    }
    if (result.affectedRows === 0) {
        res.cc(0, '未找到匹配的项圈进行修改'); // 或者根据业务逻辑返回失败
    } else {
       res.cc(200, '项圈信息修改成功'); // 使用 res.cc
    }
  });
});






//环境设备管理

//获取环境设备列表信息 (模糊分页查询)
router.get('/evmSearch', (req, res) => {
  let { pageSize, pageNum, houseId, pastureId } = req.query;

  // 并且提供默认值，例如每页10条，从第一页开始
  const parsedPageSize = parseInt(pageSize) || 5;
  const parsedPageNum = parseInt(pageNum) || 1;
  const offset = (parsedPageNum - 1) * parsedPageSize;
  let sql;
  let sql1;
  if (!houseId && !pastureId) {
    sql = `SELECT
  h.*,
  hh.F_Title AS house_Title,
  pp.F_Title AS pasture_Title
  FROM nc_setting AS h
  LEFT JOIN nc_pasture pp ON h.F_Org_Id = pp.F_Id
  LEFT JOIN nc_house hh ON h.F_HouseId = hh.F_Id
  LIMIT ${offset}, ${parsedPageSize}`;
    sql1 = `select count(*) as total from nc_setting`;
  } else {
    sql = `SELECT
   h.*,
  hh.F_Title AS house_Title,
  pp.F_Title AS pasture_Title
  FROM nc_setting AS h
  LEFT JOIN nc_pasture pp ON h.F_Org_Id = pp.F_Id
  LEFT JOIN nc_house hh ON h.F_HouseId = hh.F_Id
WHERE h.F_HouseId LIKE '%${houseId}%' OR h.F_Org_Id LIKE '%${pastureId}%'
LIMIT ${offset}, ${parsedPageSize}`;
    sql1 = `select count(*) as total from nc_setting where F_HouseId LIKE '%${houseId}%' OR F_Org_Id LIKE '%${pastureId}%'`;
  }
console.log(sql);

  db.query(sql, (err, result) => {
    if (err) {
      res.cc(0, '服务器错误',err); // 使用 res.cc
      return;
    } else if (result.length === 0) {
      res.cc(0, '暂无数据'); // 使用 res.cc
      return;
    }
    //获取总条数
    db.query(sql1, (err, countResult) => {
      if (err) {
        res.cc(0, '获取总条数失败'); // 使用 res.cc
        return;
      }
      res.send({code:200,message: '环境设备列表查询成功', data:result,total:countResult[0].total}); // 使用 res.cc
    });
  });
});

//获取环境设备信息详情
router.get('/evmDetail', (req, res) => {
  let { id } = req.query;
  let sql =
    `select h.*,n.F_Title as pasture_Title ,m.F_Title as house_Title
  from nc_setting h
  left join nc_pasture n on h.F_Org_Id = n.F_Id
  left join nc_house m on h.F_HouseId = m.F_Id
  where h.F_Id ='${id}'`;
  console.log(sql);

  db.query(sql, [id], (err, result) => {
    if (err) {
      res.cc(0, '服务器错误'); // 使用 res.cc
      return;
    }if(result.length === 0){
      res.cc(0, '暂无数据'); // 使用 res.cc
      return;
    }
    res.cc(200, '查询成功', result[0]); // 使用 res.cc 返回单条数据
  });
});

//环境设备信息批量删除
router.post('/evmDelete', (req, res) => {
  let { ids } = req.body;
  console.log(ids);
  if (!ids || ids.length === 0) {
    res.cc(0, '请选择要删除的环境设备'); // 使用 res.cc
    return;
  }
  const idList = Array.isArray(ids) ? ids : [ids];
  const idString = "'" + idList.join("','") + "'";
  let sql = `delete from nc_setting where F_id in (${idString})`;
  console.log(sql);
  db.query(sql, (err, result) => {
    if (err) {
      res.cc(0, '删除失败'); // 使用 res.cc
      return;
    }
    if (result.affectedRows === 0) {
       res.cc(0, '未找到匹配的环境设备进行删除'); // 或者根据业务逻辑返回失败
    } else {
       res.cc(200, '删除成功'); // 使用 res.cc
    }
  });
});


//新增环境设备信息(待修改 表的关联性)
router.post('/evmAdd', (req, res) => {
  let { imei, brand, houseId,pastureId } = req.body;
  const id = Date.now(); // 使用 const
  if (!imei || !brand || !houseId || !pastureId) { // 增加输入验证
     return res.cc(0, '输入字段有误');
  }
  let sql = `insert into nc_setting(F_id,F_IMEI,F_Brand,F_HouseId,F_Org_Id) values('${id}','${imei}','${brand}','${houseId}','${pastureId}')`;
  console.log(sql);
  db.query(sql, (err, result) => {
    if (err) {
      console.error("数据库错误:", err);
      return res.cc(0, '数据库操作失败'); // 使用 res.cc
    }
    res.cc(200, '环境设备信息新增成功'); // 使用 res.cc
  });
});

// 修改环境设备信息
router.post('/evmUpdate', (req, res) => {
  let { id, imei, brand, houseId,pastureId} = req.body;
  if (!id || !imei || !brand || !houseId || !pastureId) { // 增加输入验证
     return res.cc(0, '输入字段不完整或ID缺失');
  }
  let sql = `update nc_setting set F_IMEI = '${imei}',F_Brand = '${brand}',F_HouseId = '${houseId}',F_Org_Id='${pastureId}' where F_id = '${id}'`;
  console.log(sql);
  db.query(sql, (err, result) => {
    if (err) {
      console.error("数据库错误:", err);
      return res.cc(0, '环境设备信息修改失败'); // 使用 res.cc
    }
     if (result.affectedRows === 0) {
        res.cc(0, '未找到匹配的环境设备进行修改'); // 或者根据业务逻辑返回失败
    } else {
       res.cc(200, '环境设备信息修改成功'); // 使用 res.cc
    }
  });
});







//视频监控设备管理

//获取视频监控设备列表信息 (模糊分页查询)
router.get('/monSearch', (req, res) => {
  let { pageSize, pageNum, sequence, monPoints } = req.query;

  // 并且提供默认值，例如每页10条，从第一页开始
  const parsedPageSize = parseInt(pageSize) || 5;
  const parsedPageNum = parseInt(pageNum) || 1;
  const offset = (parsedPageNum - 1) * parsedPageSize;
  let sql;
  let sql1;
  if (!sequence && !monPoints) {
    sql = `SELECT
  h.*,
  pp.F_Title AS pasture_Title
  FROM nc_device_video AS h
  LEFT JOIN nc_pasture pp ON h.F_Org_Id = pp.F_Id
  LIMIT ${offset}, ${parsedPageSize}`;
    sql1 = `select count(*) as total from nc_device_video`;
  } else {
    sql = `SELECT
   h.*,
  pp.F_Title AS pasture_Title
  FROM nc_device_video AS h
  LEFT JOIN nc_pasture pp ON h.F_Org_Id = pp.F_Id
WHERE h.F_Sequence LIKE '%${sequence}%' OR h.F_Title LIKE '%${monPoints}%'
LIMIT ${offset}, ${parsedPageSize}`;
    sql1 = `select count(*) as total from nc_device_video where F_Sequence LIKE '%${sequence}%' OR F_Title LIKE '%${monPoints}%'`;
  }
console.log(sql);

  db.query(sql, (err, result) => {
    if (err) {
      res.cc(0, '服务器错误'); // 使用 res.cc
      return;
    } else if (result.length === 0) {
      res.cc(0, '暂无数据'); // 使用 res.cc
      return;
    }
    //获取总条数
    db.query(sql1, (err, countResult) => {
      if (err) {
        res.cc(0, '获取总条数失败'); // 使用 res.cc
        return;
      }
      res.send({code:200,message: '视频监控设备列表查询成功', data:result,total: countResult[0].total}); // 使用 res.cc
    });
  });
});

//获取视频监控信息详情
router.get('/monDetail', (req, res) => {
  let { id } = req.query;
  let sql =
    `select h.*,n.F_Title as pasture_Title
  from nc_device_video h
  left join nc_pasture n on h.F_Org_Id = n.F_Id
  where h.F_Id ='${id}'`;
  console.log(sql);

  db.query(sql, [id], (err, result) => {
    if (err) {
      res.cc(0, '服务器错误'); // 使用 res.cc
      return;
    }if(result.length === 0){
      res.cc(0, '暂无数据'); // 使用 res.cc
      return;
    }
    res.cc(200, '查询成功', result[0]); // 使用 res.cc 返回单条数据
  });
});

//视频监控信息批量删除
router.post('/monDelete', (req, res) => {
  let { ids } = req.body;
  console.log(ids);
  if (!ids || ids.length === 0) {
    res.cc(0, '请选择要删除的视频监控信息'); // 使用 res.cc
    return;
  }
  const idList = Array.isArray(ids) ? ids : [ids];
  const idString = "'" + idList.join("','") + "'";

  // TODO: 在删除数据库记录之前，考虑删除对应的文件
  // 批量删除文件需要先查询所有要删除记录的文件路径
   let selectSql = `SELECT F_Headimg FROM nc_device_video WHERE F_id IN (${idString})`;
   db.query(selectSql, (err, fileResults) => {
       if (err) {
           console.error("查询待删除文件路径失败:", err);
           // 即使文件查询失败，也继续尝试删除数据库记录
       } else {
           // 异步删除文件
           fileResults.forEach(fileRow => {
               const fileUrl = fileRow.F_Headimg;
               if (fileUrl) {
                   // 构建旧文件的物理路径 (相对于项目根目录)
                   const filePath = path.join(__dirname, '../../', 'public', fileUrl.replace('/upload/', 'upload/'));
                   fs.unlink(filePath, (unlinkErr) => {
                       if (unlinkErr) {
                           // 如果文件不存在或删除失败，只记录错误，不中断批量删除流程
                           console.error(`删除文件失败: ${filePath}`, unlinkErr);
                       } else {
                           console.log(`文件删除成功: ${filePath}`);
                       }
                   });
               }
           });
       }

        // 执行数据库删除
       let deleteSql = `delete from nc_device_video where F_id in (${idString})`;
       console.log(deleteSql);
       db.query(deleteSql, (err, result) => {
         if (err) {
           res.cc(0, '删除失败'); // 使用 res.cc
           return;
         }
         if (result.affectedRows === 0) {
            res.cc(0, '未找到匹配的视频监控信息进行删除'); // 或者根据业务逻辑返回失败
         } else {
            res.cc(200, '删除成功'); // 使用 res.cc
         }
       });
   });
});


// 新增视频监控信息信息 - 包含文件重命名逻辑
router.post('/monAdd', (req, res) => {
  // 1. 输入验证 (在执行SQL之前)
  const { title, sequence, channel, code, token, address, pastureId } = req.body;

  // 2. 获取文件信息（从全局 Multer 处理后的 req.files 中获取）
  // objMulter.any() 会将文件信息放在 req.files 对象中，键是文件字段名
  // 从 req.files 数组中查找 fieldname 为 'headimg' 的文件
  const uploadedFile = req.files && Array.isArray(req.files) ? req.files.find(file => file.fieldname === 'headimg') : undefined;

  // 先检查文件是否存在，再检查其他字段
  if (!uploadedFile) {
    // 如果没有上传文件，且其他必填字段也不完整，直接返回错误
    if (!title || !sequence || !channel || !code || !token || !address || !pastureId) {
        return res.cc(0, '输入字段不完整且未上传文件');
    }
     // 如果其他字段完整但没有文件，根据业务需求判断是否允许
     // 这里假设文件是必须的
     return res.cc(0, '未选择文件或文件上传失败');
  }

  // 如果文件已上传，再检查其他必填字段
   if (!title || !sequence || !channel || !code || !token || !address || !pastureId) {
    // 如果输入字段不完整，删除 Multer 已经上传的临时文件
    fs.unlink(uploadedFile.path, (unlinkErr) => {
      if (unlinkErr) console.error("删除不完整请求的上传文件失败:", unlinkErr);
    });
    return res.cc(0, '输入字段不完整');
  }


  console.log("req.files:", req.files);
  console.log("获取的文件名:", path.extname(uploadedFile.originalname)); // 使用 uploadedFile


  // 3. 获取原始文件名和 Multer 保存的临时路径
  const originalName = uploadedFile.originalname; // 原始文件名，例如 "myphoto.jpg"
  const oldPath = uploadedFile.path; // Multer 保存的临时路径，例如 "./public/upload/ea5d5840dabe0e65267a4f9f8c8258ec"
  const directory = path.dirname(oldPath); // 保存文件的目录，例如 "./public/upload"
  const baseName = path.basename(oldPath); // Multer 生成的随机文件名（无扩展名），例如 "ea5d5840dabe0e65267a4f9f8c8258ec"
  const ext = path.extname(originalName); // 原始文件的扩展名，例如 ".jpg"

  // 4. 构建新的文件名和路径（包含原始扩展名）
  const newFilename = baseName + ext; // 新的文件名，例如 "ea5d5840dabe0e65267a4f9f8c8258ec.jpg"
  const newPath = path.join(directory, newFilename); // 新的完整路径，例如 "./public/upload/ea5d5840dabe0e65267a4f9f8c8258ec.jpg"

  // 5. 重命名文件，将扩展名加上去
  fs.rename(oldPath, newPath, (renameErr) => {
    if (renameErr) {
      console.error("重命名文件失败:", renameErr);
      // 如果重命名失败，尝试删除已上传的临时文件
      fs.unlink(oldPath, (unlinkErr) => {
        if (unlinkErr) console.error("删除重命名失败的文件失败:", unlinkErr);
      });
      return res.cc(0, '文件处理失败'); // 使用 res.cc
    }

    // 文件重命名成功后，构建可访问的 URL
    // 假设您的静态服务在 app.js 中将 /upload 映射到 ./public/upload
    const fileUrl = `/upload/${newFilename}`; // 使用重命名后的文件名构建 URL

    // 6. 生成其他字段
    const id = Date.now(); // id为时间戳
    const createTime = new Date().toISOString().replace('T', ' ').substring(0, 19); // 获取创建日期

    // 7. 构建参数化查询 (防止SQL注入)
    // 注意：请根据您的 db 库的参数化查询语法进行调整
    // 假设您的 db.query 支持 ? 占位符和值数组
    // 字段映射：
    // req.body.sequence -> F_Sequence
    // req.body.title -> F_Title
    // req.body.channel -> F_Channel
    // req.body.code -> F_Code
    // req.body.address -> F_Address
    // req.body.pastureId -> F_Org_Id
    // fileUrl -> F_Headimg
    // createTime -> F_CreateTime
    // req.body.token -> F_Token (如果数据库中有此字段，且需要保存)
    // 假设 F_Token 字段存在且需要保存 token
     let sql = `INSERT INTO nc_device_video(F_Id, F_Sequence, F_Title, F_Channel, F_Headimg, F_Code, F_Token, F_Address, F_Org_Id, F_CreateTime)
               VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;

    const values = [
      id,
      sequence,
      title,
      channel,
      fileUrl, // 将带有扩展名的文件 URL 保存到数据库
      code,
      token, // 保存 token
      address,
      pastureId,
      createTime
    ];


    console.log("SQL:", sql); // 打印 SQL 结构 (不含实际值，防止日志泄露敏感信息)
    console.log("Values:", values); // 打印值数组

    // 8. 执行查询
    db.query(sql, values, (err, result) => { // 将值数组作为第二个参数传递
      if (err) {
        console.error("数据库错误:", err); // 记录详细错误日志
        // 如果数据库操作失败，尝试删除已重命名好的文件
        fs.unlink(newPath, (unlinkErr) => { // 注意这里删除的是重命名后的文件
          if (unlinkErr) console.error("删除数据库操作失败的上传文件失败:", unlinkErr);
        });
        return res.cc(0, '数据库操作失败'); // 使用 res.cc
      }

      // 9. 返回成功响应
      res.cc(200, '视频监控信息新增成功', { // 使用 res.cc 返回数据
         url: `http://127.0.0.1:9999${fileUrl}` // 返回完整的可访问URL
      });
    });
  }); // fs.rename 结束
});


// 修改视频监控信息 - 包含文件处理逻辑
router.post('/monUpdate', (req, res) => {
    // 1. 获取请求数据
    const { id, title, sequence, channel, code, token, address, pastureId } = req.body;

    // 2. 验证 ID 是否存在
    if (!id) {
        return res.cc(0, '缺少要修改的记录ID');
    }

    // 3. 获取文件信息（从全局 Multer 处理后的 req.files 中获取）
    const uploadedFile = req.files && Array.isArray(req.files) ? req.files.find(file => file.fieldname === 'headimg') : undefined;

    // 4. 查询旧的文件路径 (无论是否上传新文件，都需要先查，以便后续删除旧文件)
    const getOldFileSql = `SELECT F_Headimg FROM nc_device_video WHERE F_Id = ?`;
    db.query(getOldFileSql, [id], (err, result) => {
        if (err) {
            console.error("查询旧文件路径失败:", err);
            // 如果查询旧文件路径失败，且上传了新文件，需要清理 Multer 生成的临时文件
            if (uploadedFile) {
                 fs.unlink(uploadedFile.path, (unlinkErr) => {
                    if (unlinkErr) console.error("删除查询旧文件路径失败时的上传文件失败:", unlinkErr);
                });
            }
            return res.cc(0, '查询旧文件路径失败');
        }

        // 如果找不到对应的记录，直接返回错误
        if (result.length === 0) {
             // 如果上传了文件，需要清理 Multer 生成的临时文件
            if (uploadedFile) {
                 fs.unlink(uploadedFile.path, (unlinkErr) => {
                    if (unlinkErr) console.error("删除找不到记录的上传文件失败:", unlinkErr);
                });
            }
            return res.cc(0, '未找到要修改的视频监控信息');
        }

        const oldFileUrl = result.length > 0 ? result[0].F_Headimg : null; // 获取旧的文件 URL，如果不存在则为 null

        // 5. 处理文件上传和重命名 (如果上传了新文件)
        if (uploadedFile) {
            const originalName = uploadedFile.originalname;
            const oldPath = uploadedFile.path; // Multer 保存的临时路径
            const directory = path.dirname(oldPath); // 保存文件的目录
            const baseName = path.basename(oldPath); // Multer 生成的随机文件名（无扩展名）
            const ext = path.extname(originalName); // 原始文件的扩展名

            const newFilename = baseName + ext; // 新的文件名
            const newPath = path.join(directory, newFilename); // 新的完整路径
            const newFileUrl = `/upload/${newFilename}`; // 新的文件 URL

            // 重命名文件
            fs.rename(oldPath, newPath, (renameErr) => {
                if (renameErr) {
                    console.error("重命名文件失败:", renameErr);
                    // 如果重命名失败，尝试删除已上传的临时文件
                    fs.unlink(oldPath, (unlinkErr) => {
                        if (unlinkErr) console.error("删除重命名失败的文件失败:", unlinkErr);
                    });
                    return res.cc(0, '文件处理失败');
                }

                // 文件重命名成功后，构建 UPDATE 语句
                // 将新文件 URL 包含在 updateFields 中
                updateDatabase(id, { title, sequence, channel, code, token, address, pastureId, headimg: newFileUrl }, oldFileUrl, res, newPath);
            });

        } else {
            // 6. 如果没有上传新文件，直接更新数据库（不包含文件字段）
            updateDatabase(id, { title, sequence, channel, code, token, address, pastureId }, oldFileUrl, res, null);
        }
    });
});

// 辅助函数：执行数据库更新和后续清理
function updateDatabase(id, updateFields, oldFileUrl, res, newPath = null) {
    // 构建动态 SET 子句和 values 数组
    const setClauses = [];
    const values = [];

    // 映射请求字段到数据库字段
    const fieldMapping = {
        sequence: 'F_Sequence',
        title: 'F_Title',
        channel: 'F_Channel',
        code: 'F_Code',
        token: 'F_Token', // 假设 F_Token 字段存在且需要更新 token
        address: 'F_Address',
        pastureId: 'F_Org_Id',
        headimg: 'F_Headimg' // 文件字段
    };

    for (const field in updateFields) {
        // 检查字段是否存在于 fieldMapping 且值不是 undefined 或 null
        // 并且确保文件字段只有在 newPath 存在时才加入更新
        if (fieldMapping[field] && updateFields[field] !== undefined && updateFields[field] !== null) {
             if (field === 'headimg' && newPath === null) {
                 continue; // 如果没有新文件，跳过文件字段
            }
            setClauses.push(`${fieldMapping[field]} = ?`);
            values.push(updateFields[field]);
        }
    }

    // 如果没有要更新的字段（除了ID），直接返回
    if (setClauses.length === 0) {
         // 如果上传了文件，需要清理新文件
        if (newPath) {
             fs.unlink(newPath, (unlinkErr) => {
                if (unlinkErr) console.error("删除无更新字段的新上传文件失败:", unlinkErr);
            });
        }
        return res.cc(0, '没有提供要更新的字段');
    }

    // 添加 WHERE 子句的 ID
    values.push(id);

    const sql = `UPDATE nc_device_video SET ${setClauses.join(', ')} WHERE F_Id = ?`;
    console.log("UPDATE SQL:", sql);
    console.log("UPDATE Values:", values);

    db.query(sql, values, (err, result) => {
        // 在回调函数内部定义 newFileUrl，从 updateFields 中获取
        const updatedFileUrl = updateFields.headimg; // 从 updateFields 中获取新文件 URL (如果存在)

        if (err) {
            console.error("数据库更新失败:", err); // 记录详细错误日志
             // 如果数据库操作失败，且上传了新文件，需要删除新文件
            if (newPath) {
                 fs.unlink(newPath, (unlinkErr) => {
                    if (unlinkErr) console.error("删除数据库更新失败的新上传文件失败:", unlinkErr);
                });
            }
            return res.cc(1, '数据库更新失败');
        }

        // 检查是否修改了任何行
        if (result.affectedRows === 0) {
             // 如果上传了文件，需要清理新文件
            if (newPath) {
                 fs.unlink(newPath, (unlinkErr) => {
                    if (unlinkErr) console.error("删除未找到记录的新上传文件失败:", unlinkErr);
                });
            }
            return res.cc(0, '未找到匹配的视频监控信息进行修改'); // 或者根据业务逻辑返回失败
        }

        // 如果数据库更新成功且上传了新文件，删除旧文件
        if (newPath && oldFileUrl) {
            // 构建旧文件的物理路径 (相对于项目根目录)
            // __dirname 是当前文件 (device.js) 的目录 D:\...\api\routes\admin
            // '../../' 回退两级到项目根目录 D:\...\api
            // 'public' 进入 public 目录 D:\...\api\public
            // oldFileUrl.replace('/upload/', 'upload/') 将 /upload/filename.ext 变为 upload/filename.ext
            // 最终路径 D:\...\api\public\upload\filename.ext
            const oldFilePath = path.join(__dirname, '../../', 'public', oldFileUrl.replace('/upload/', 'upload/'));
            console.log("尝试删除旧文件:", oldFilePath);
            fs.unlink(oldFilePath, (unlinkErr) => {
                if (unlinkErr) {
                    // 如果旧文件删除失败，只记录错误，不影响主流程的成功响应
                    console.error("删除旧文件失败:", oldErr); // 修正变量名 unlinkErr -> oldErr
                } else {
                    console.log("旧文件删除成功:", oldFilePath);
                }
            });
        }

        // 返回成功响应
        // 使用 updatedFileUrl (从 updateFields 获取) 来构建返回的 URL
        res.cc(200, '视频监控信息修改成功', updatedFileUrl ? { url: `http://127.0.0.1:9999${updatedFileUrl}` } : undefined); // 如果有新文件，返回新 URL
    });
}


module.exports = router;
